package dubbo.learn.core.config.parser;

import dubbo.learn.core.beanfactorypostprocessor.RedissonConfigBeanDefinitionPostProcessor;
import dubbo.learn.registry.redis.RedisRegistry;
import dubbo.learn.core.util.BeanDefinitionRegistryUtil;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.w3c.dom.Element;

/**
 * 注册中心的bean解析
 */
public class RegistryBeanDefinitionParser implements BeanDefinitionParser {
    public static final String ADDRESS = "address";

    public static final String REDISSON_XML_CONFIG_PATH = "classpath:redisson.xml";



    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        /**
         * 解析xml配置
         */
        String address = element.getAttribute("address");
        if (address == null) {
            throw new RuntimeException();
        }
        if (address.startsWith("redis")) {
            /**
             * 生成bean definition
             */
            RootBeanDefinition rootBeanDefinition = createRedisRegistryDefinition(address);
            BeanDefinitionRegistry registry = parserContext.getRegistry();
            String beanName = AnnotationBeanNameGenerator.INSTANCE.generateBeanName(rootBeanDefinition, registry);
            registry.registerBeanDefinition(beanName, rootBeanDefinition);

            /**
             * 注册 redisson 相关的bean
             */
            parserContext.getReaderContext().getReader().loadBeanDefinitions(REDISSON_XML_CONFIG_PATH);

            /**
             * 注册bean factory后置处理器，让redisson连接的redis地址，
             * 使用<dubbo:registry address="redis://127.0.0.1:6379"/> 元素里配置的这个地址
             */
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RedissonConfigBeanDefinitionPostProcessor.class);
            BeanDefinitionRegistryUtil.registerBeanDefinition(registry,builder.getBeanDefinition());

        } else {
            throw new UnsupportedOperationException();
        }

        return null;
    }

    protected RootBeanDefinition createRedisRegistryDefinition(String address) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(RedisRegistry.class);
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        beanDefinition.setSynthetic(true);
        beanDefinition.getPropertyValues().add(ADDRESS, address);
        return beanDefinition;
    }
}
